using Engine.Graphics;
using Engine.TrafficHelpers;
using System;
using System.Windows.Forms;

namespace street
{
    public partial class PropertiesForCRUI : UserControl
    {
        #region Private Fields

        private Scenario_Editor.AddinManager.IMaterialEditorControl _materialEditControl;
        private IMaterial _materialRail;
        private PropertiesCR[] crossroadProperties;
        private bool duringControlUpdate = false;
        private IMaterial materialForRail;

        #endregion Private Fields

        #region Public Constructors

        public PropertiesForCRUI()
        {
            InitializeComponent();
            this.duringControlUpdate = true;
            this.crossroadProperties = new PropertiesCR[0];
            this.checkBox_CRRailRight.Visible = false;
            this.label_RailRight.Visible = false;
            this.label_RailLeft.Text = "Rail";

            this.duringControlUpdate = false;
        }

        #endregion Public Constructors

        #region Public Methods

        public PropertiesCR[] GetCrossroadProperties(int numberOfstreets)
        {
            PropertiesCR[] crossroadProperties = new PropertiesCR[numberOfstreets];
            // If there there are to little

            if (numberOfstreets >= crossroadProperties.Length)
                UpdateNumberOfProperties(numberOfstreets);

            for (int i = 0; i < numberOfstreets; i++)
            {
                crossroadProperties[i] = this.crossroadProperties[i];
            }
            return crossroadProperties;
        }

        public CrossroadTraffic[] GetTrafficDataForCrossroad(PropertiesCR[] roadProperties, int numberOfStreets)
        {
            CrossroadTraffic[] traffic = new CrossroadTraffic[numberOfStreets];

            for (int i = 0; i < numberOfStreets; i++)
            {
                traffic[i] = roadProperties[i].Traffic;
            }
            return traffic;
        }

        public void OnAddinChange(object sender, EventArgs e)
        {
            if (this._materialEditControl != null)
            {
                // Remove control and events from old materialPainter.
                this._materialEditControl.MaterialChanged -= Propertie_ValueChanged;
                this.panel1.Controls.Clear();
            }

            this.addin = (Scenario_Editor.AddinManager.IAddinScenarioEditor)sender;

            this._materialEditControl = this.addin.GetNewMaterialEditControl();
            if (this._materialEditControl is Control)
            {
                Control control = (Control)this._materialEditControl;
                control.Dock = DockStyle.Fill;
                this.tableLayoutPanel2.RowStyles[0].Height = control.Height + this.tableLayoutPanel2.Margin.Top + this.tableLayoutPanel2.Margin.Bottom;
                this.panel1.Controls.Add(control);
            }
            else
                throw new Exception("Can't add material edit control to Roadproperties tab.");

            if (this._materialEditControl is Scenario_Editor.AddinManager.IMaterialEditorControl)
            {
                this._materialEditControl.MaterialChanged += Propertie_ValueChanged;
                // Set new Material
                int selectedCrossroad = (int)this.numericUpDown_selectedStreet.Value - 1;

                for (int i = 0; i < this.crossroadProperties.Length; i++)
                {
                    var property = this.crossroadProperties[i];
                    property.MaterialForRoad = this._materialEditControl.GetNewMaterial();
                    property.MaterialForRail = this._materialRail;
                    this.crossroadProperties[i] = property;
                }
            }
            else
                throw new Exception("No Material Edit Control can set in Road Properties Control.");
        }

        public void SetCrossroadProperties(PropertiesCR[] value)
        {
            this.crossroadProperties = new PropertiesCR[value.Length];
            value.CopyTo(this.crossroadProperties, 0);
            Index_ValueChanged(null, null);
        }

        public void SetTrafficDataForCrossroad(CrossroadTraffic[] value)
        {
            for (int i = 0; i < value.Length; i++)
            {
                this.crossroadProperties[i].Traffic = value[i];
            }
        }

        #endregion Public Methods

        #region Internal Methods

        internal IMaterial GetCurrentMaterial()
        {
            return this._materialEditControl.GetNewMaterial();
        }

        internal void SetAsphaltMaterial(IMaterial material)
        {
            this._materialEditControl.SetMaterial(material);
        }

        internal void SetRailMaterial(IMaterial material)
        {
            this._materialRail = material;
        }

        #endregion Internal Methods

        #region Private Methods

        private Scenario_Editor.AddinManager.IAddinScenarioEditor addin;

        private Engine.Graphics.MaterialStorage materialStorage;

        private void Index_ValueChanged(object sender, EventArgs e)
        {
            this.duringControlUpdate = true;
            {
                if (this.numericUpDown_selectedStreet.Value > this.crossroadProperties.Length)
                    this.numericUpDown_selectedStreet.Value = this.crossroadProperties.Length;

                int selectedCrossroad = (int)this.numericUpDown_selectedStreet.Value - 1;

                this.crossroadTrafficControl.SetCrossroadTraffic(this.crossroadProperties[selectedCrossroad].Traffic);

                PropertiesCR cr = this.crossroadProperties[selectedCrossroad];

                cr.MaterialForRoad = this._materialEditControl.GetNewMaterial();
                cr.MaterialForRail = this._materialRail;
                // throw new NotImplementedException("Set Material Edit Control.");

                this.numericUpDown_StreetWidth.Value = (decimal)cr.Streetwidth;
                this.checkBox_CRRailLeft.Checked = Convert.ToBoolean(cr.RailLeft);
                this.checkBox_CRRailRight.Checked = Convert.ToBoolean(cr.RaiRight);
            }
            this.duringControlUpdate = false;
        }

        private void Propertie_ValueChanged(object sender, EventArgs e)
        {
            if (!this.duringControlUpdate && this.crossroadProperties.Length > 0)
            {
                int selectedCrossroad = (int)this.numericUpDown_selectedStreet.Value - 1;

                // Create new data when there are insufficient entries.
                if (this.crossroadProperties.Length < selectedCrossroad + 1)
                {
                    UpdateNumberOfProperties(selectedCrossroad);
                }

                PropertiesCR cr = this.crossroadProperties[selectedCrossroad];

                cr.Traffic = this.crossroadTrafficControl.GetCrossroadTraffic();
                cr.Streetwidth = (float)this.numericUpDown_StreetWidth.Value;
                cr.RaiRight = Convert.ToInt32(this.checkBox_CRRailRight.CheckState);
                cr.RailLeft = Convert.ToInt32(this.checkBox_CRRailLeft.CheckState);
                this.crossroadProperties[selectedCrossroad] = cr;

                //Update the material
                cr.MaterialForRail = this._materialRail;
                cr.MaterialForRoad = this._materialEditControl.GetNewMaterial();
                this.crossroadProperties[selectedCrossroad] = cr;

                streetTool.hasPropertiesChanged = true;
            }
        }

        private void UpdateNumberOfProperties(int numberOfstreets)
        {
            int currentNumber = this.crossroadProperties.Length;
            Array.Resize(ref this.crossroadProperties, numberOfstreets);

            for (int i = currentNumber; i < numberOfstreets; i++)
            {
                this.crossroadProperties[i].RailLeft = Convert.ToInt32(this.checkBox_CRRailLeft.Checked);
                this.crossroadProperties[i].RaiRight = Convert.ToInt32(this.checkBox_CRRailRight.Checked);
                this.crossroadProperties[i].Streetwidth = (float)this.numericUpDown_StreetWidth.Value;

                this.crossroadProperties[i].MaterialForRoad = this._materialEditControl.GetNewMaterial();
                this.crossroadProperties[i].MaterialForRail = this._materialRail;

                this.crossroadProperties[i].Traffic = this.crossroadTrafficControl.GetCrossroadTraffic();
            }
        }

        #endregion Private Methods
    }
}